import java.awt.geom.Point2D.Double;

/** 
 * Encapsula funcionalidades de um vetor bidimensional.
 * Os atributos x e y são publicos.
 * @author Rodrigo
 */
public class Vetor2D extends Double{

	public Vetor2D() {
		super();
	}
	
	public Vetor2D(double x, double y) {
		super(x, y);
	}	
	
	public Vetor2D(Double ponto) {
		super(ponto.x, ponto.y);
	}
	
	/**
	 * Retorna objeto que representa o angulo do vetor,
	 * em relação a origem
	 * @return angulo
	 */
	public double angulo() {
		return Math.atan2(y, x);
	}

	/**
	 * Retorna comprimento do vetor(modulo)
	 * @return modulo
	 */
	public double comprimento() {
		return Math.sqrt(x * x + y * y);
	}

	/**
	 * Soma este com outro vetor, retornando vetor que
	 * representa a soma
	 * @param vector
	 * @return soma
	 */
	public Vetor2D somar(Vetor2D vector) {
		return new Vetor2D(x + vector.x, y + vector.y);
	}
	
	/**
	 * Multiplica este com outro vetor, retornando vetor que
	 * representa o produto
	 * @param vector
	 * @return produto
	 */
	public Vetor2D multiplicar(Vetor2D vector) {
		return new Vetor2D(x * vector.x, y * vector.y);
	}	
	
	/**
	 * Divide este por outro vetor, retornando vetor que
	 * representa a divisão
	 * @param vector
	 * @return quociente
	 */
	public Vetor2D dividir(Vetor2D vector) {
		return new Vetor2D(x / vector.x, y / vector.y);
	}	

	/**
	 * Subtrai deste outro vetor, retornando a subtração
	 * @param vector
	 * @return subtração
	 */
	public Vetor2D subtrair(Vetor2D vector) {
		return new Vetor2D(x - vector.x, y - vector.y);
	}

	/**
	 * Escala o vetor, mutiplicando pelo escalar dado
	 * no parametro
	 * @param scalar
	 * @return vetor escalado
	 */
	public Vetor2D escalar(double scalar) {
		return new Vetor2D(scalar * x, scalar * y);
	}

	/**
	 * Realiza o produto escalar deste com outro vetor
	 * @param that
	 * @return produto escalar
	 */
	public double produtoEscalar(Double that) {
		return this.x * that.x + this.y * that.y;
	}

	/**
	 * Gira(rotaciona) este vetor na origem
	 * @param angulo
	 * @return vetor rotacionado
	 */
	public Vetor2D girar(double angulo) {
		double cos = Math.cos(angulo);
		double sin = Math.sin(angulo);
		return new Vetor2D(x * cos - y * sin, x * sin + y * cos);
	}

	/**
	 * Compara este objeto com outro objeto
	 */
	public boolean equals(Object thatObject) {
		if (thatObject instanceof Vetor2D) {
			Vetor2D that = (Vetor2D) thatObject;
			return this.x == that.x && this.y == that.y;
		} else {
			return false;
		}
	}

	/**
	 * Retorna codigo hash deste objeto
	 */
	public int hashCode() {
		return (int) (x + y);
	}

	/**
	 * Retorna um vetor que é ortogonal a esse pela esquerda
	 * @return vetor ortogonal a esquerda
	 */
	public Vetor2D ortogonal() {
		return new Vetor2D(-y, x);
	}

	/**
	 * Produz um vetor unitario com mesma direção e sentido deste
	 * @return vetor unitario
	 */
	public Vetor2D normalisar() {
		double length = comprimento();
		return length > 0.0 ? escalar(1.0 / length) : this;
	}

	/**
	 * Muda o sentido do vetor
	 * @return vetor negado
	 */
	public Vetor2D negar() {
		return new Vetor2D(-x, -y);
	}

}
